package models

import (
	"errors"
	"time"

	"gitee.com/sansaniot/ssiot-core/httpmvc/model"
	"gorm.io/datatypes"

	"ssdevice/common/constant"
	cDto "ssdevice/common/dto"
	"ssdevice/common/utils"
	"ssdevice/internal/device/models/query"
)

type SysDevProduct struct {
	Id           string          `json:"id" gorm:"primaryKey;type:varchar(255);comment:id"`
	Name         string          `json:"name" gorm:"type:varchar(255);comment:产品名称,具有唯一性(如定义为产品型号)"`
	DeviceType   string          `json:"deviceType" gorm:"type:varchar(255);comment:网关:gateway 设备:device 软网关:soft_gateway"`
	Status       bool            `json:"status" gorm:"type:bool;comment:是否已发布"`
	ProductModel string          `json:"model" gorm:"column:model;type:varchar(255);comment:产品编码"`
	DeptId       string          `json:"deptId" gorm:"type:varchar(255);comment:分组id"`
	Photo        string          `json:"photo" gorm:"type:varchar(255);comment:产品图片"`
	Description  string          `json:"description" gorm:"type:text;comment:描述"`
	CreateTime   *cDto.LocalTime `json:"createTime" gorm:"type:timestamptz(6);comment:创建时间"`
	UpdateTime   *cDto.LocalTime `json:"updateTime" gorm:"type:timestamptz(6);comment:更新时间"`
	View         datatypes.JSON  `json:"view" gorm:"type:jsonb;comment:个性页"`
	model.Model

	DeptName string `json:"deptName" gorm:"-"`
}

func (SysDevProduct) TableName() string {
	return "sys_dev_product"
}

func (e *SysDevProduct) Generate() interface{} {
	o := *e
	return &o
}

func (e *SysDevProduct) GetId() interface{} {
	return e.Id
}

func (e *SysDevProduct) FindProductList(req *query.SysProductQuery) (err error, result interface{}) {
	list := make([]SysDevProduct, 0)
	var count int64
	if req.PageIndex > 0 && req.PageSize > 0 {
		err = e.FindPage(&list, &count,
			cDto.MakeCondition(req.GetNeedSearch()),
			cDto.OrderDest("create_time", true, req.OrderBy),
			cDto.Paginate(req.GetPageSize(), req.GetPageIndex()),
		)
		groupIdName, _ := utils.GroupIdName(e.Orm)
		for i := range list {
			if len(list[i].DeptId) > 0 {
				if deptName, ok := groupIdName[list[i].DeptId]; ok {
					list[i].DeptName = deptName
				}
			}
		}
		result = &cDto.Page{
			Records:   list,
			Total:     count,
			PageSize:  req.GetPageSize(),
			PageIndex: req.GetPageIndex(),
			Pages:     (count + int64(req.GetPageSize()) - 1) / int64(req.GetPageSize()),
			Other:     nil,
		}
	} else {
		err = e.FindList(&list,
			cDto.MakeCondition(req.GetNeedSearch()),
			cDto.OrderDest("create_time", true, req.OrderBy),
		)
		groupIdName, _ := utils.GroupIdName(e.Orm)
		for i := range list {
			if len(list[i].DeptId) > 0 {
				if deptName, ok := groupIdName[list[i].DeptId]; ok {
					list[i].DeptName = deptName
				}
			}
		}
		result = list
	}
	return
}

func (e *SysDevProduct) FindProduct(req *query.SysProductQuery) (err error, one SysDevProduct) {
	err = e.FindOne(&one, cDto.MakeCondition(req.GetNeedSearch()))
	if len(one.Id) > 0 && len(one.DeptId) > 0 {
		groupIdName, _ := utils.GroupIdName(e.Orm, []string{one.DeptId})
		if deptName, ok := groupIdName[one.DeptId]; ok {
			one.DeptName = deptName
		}
	}
	return
}

func (e *SysDevProduct) AddProduct(addProduct *SysDevProduct) (err error) {
	var count int64
	if err = e.FindCount(&SysDevProduct{}, &count, cDto.MakeCondition(query.SysProductQuery{ProductModel: addProduct.ProductModel})); err != nil {
		return
	}
	if count > 0 {
		err = errors.New("产品编码已存在")
		return
	}
	if err = e.Add(addProduct); err != nil {
		return
	}
	return
}

func (e *SysDevProduct) ModProduct(modFields map[string]interface{}) error {
	if len(modFields) == 0 {
		return nil
	}
	modFields["update_time"] = time.Now()
	return e.ModMap(e, modFields)
}

func (e *SysDevProduct) SetRelateDevCodeEmpty(productIds []string) error {
	// 获取productModel
	productList := make([]SysDevProduct, 0)
	if err := e.FindList(&productList, cDto.MakeCondition(query.SysProductQuery{IdIn: productIds})); err != nil {
		return err
	}
	productModels := make([]string, 0)
	for _, v := range productList {
		productModels = append(productModels, v.ProductModel)
	}
	if len(productModels) > 0 {
		dev := &SysDev{}
		dev.Orm = e.Orm
		if err := dev.ModMap(dev, map[string]interface{}{"product_model": ""}, cDto.MakeCondition(query.SysDevQuery{ProductModelIn: productModels})); err != nil {
			return err
		}
	}
	return nil
}

func (e *SysDevProduct) GetModelMapper() (mapper map[string]string) {
	mapper = make(map[string]string)
	list := make([]SysDevProduct, 0)
	if err := e.FindList(&list); err != nil {
		return
	}
	for _, v := range list {
		mapper[v.ProductModel] = v.DeviceType
	}
	return
}

func (e *SysDevProduct) GetModelName() (mapper map[string]string) {
	mapper = make(map[string]string)
	list := make([]SysDevProduct, 0)
	if err := e.FindList(&list); err != nil {
		return
	}
	for _, v := range list {
		mapper[v.ProductModel] = v.Name
	}
	return
}

func (e *SysDevProduct) GetIdModels(ids []string, userId string) (pdmodels []string, err error) {
	pdmodels = make([]string, 0)
	list := make([]SysDevProduct, 0)
	if err = e.FindList(&list, cDto.MakeCondition(query.SysProductQuery{IdIn: ids})); err != nil {
		return
	}
	for _, v := range list {
		pdmodels = append(pdmodels, v.ProductModel)
		if v.DeptId == constant.PublicGroupId && userId != "1" {
			err = errors.New("没权限操作公共分组资源")
			return
		}
	}
	return
}
